﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.SessionState;
using System.Xml;
using System.Xml.Xsl;

using NHaml;

namespace IntraVision.Web
{
    public class ControllerBase : IController
    {
        private string _Name;
        private string _Action;

        private string _TemplatePath;
        private string _LayoutPath;
        private string _UserKey;

        private HttpContext _Context;
        private HttpSessionState _Session;
        private ViewData _ViewData;

        public string Name { get { return _Name; } }
        public string Action { get { return _Action; } }

        public HttpContext Context { get { return _Context; } }
        public HttpSessionState Session { get { return _Session; } }
        public HttpRequest Request { get { return ( _Context != null ) ? _Context.Request : null; } }
        public HttpResponse Response { get { return (_Context != null) ? _Context.Response : null; } }
        public HttpServerUtility Server { get { return (_Context != null) ? _Context.Server : null; } }

        public string TemplatePath { get { return _TemplatePath; } set { _TemplatePath = value; } }
        public string LayoutPath { get { return _LayoutPath; } set { _LayoutPath = value; } }
        public string Language { get { return System.Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName.ToUpper(); } }

        public ViewData ViewData { get { return _ViewData; } }

        public ControllerBase()
        {
            _Context = HttpContext.Current;
            _ViewData = new ViewData();

            //Controller can be created in Application.OnStart for precompilation, so if Session isnot yet present we should skip initialization
            if (_Context.Session == null) return;

            _Session = _Context.Session;

            string url = _Context.Request.AppRelativeCurrentExecutionFilePath + _Context.Request.PathInfo;
            string[] urlparts = URLHelper.GetURLParts(url);

            _Name = GetType().Name.Replace("Controller", "").ToLower();
            _Action = urlparts[1].ToLower();

            _ViewData["Base"] = URLHelper.GetBaseHref(_Context);
            _ViewData["Controller"] = _Name;
            _ViewData["Action"] = _Action;

            _UserKey = ConfigurationManager.AppSettings["userKey"] ?? "user";
            if (Session[_UserKey] != null)
                _ViewData["user"] = Session[_UserKey];
        }

        public void RenderJSON(object obj)
        {
            string result;
            using (MemoryStream ms = new MemoryStream())
            {
                var serializer = new DataContractJsonSerializer(obj.GetType());
                serializer.WriteObject(ms, obj);
                result = Encoding.UTF8.GetString(ms.ToArray());
            }
            Response.Write(result);
        }

        public void RenderView()
        {
            RenderView(TemplatePath, LayoutPath);
        }

        public void RenderView(string template, string layout)
        {
            if (layout == "none" || !string.IsNullOrEmpty(Request["nolayout"]))
            {
                layout = null;
                ViewData["nolayout"] = true;
            }

            _ViewData["Language"] = Language;

            Template view = ViewFactory.GetView(this, ViewData, template, layout);
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);
            view.Render(sw);
            Response.Write(sb.ToString());
        }

        public void RedirectToAction(string controllerName, string actionName, string[] parameters)
        {
            string path = controllerName + ".ivp/" + actionName;
            if (parameters != null)
            {
                foreach (string param in parameters)
                    path += "/" + param;
            }
            Response.Redirect(path);
        }
     
        public void RedirectToAction(string actionName, string[] parameters)
        {
            RedirectToAction(Name, actionName, parameters);
        }

        public void RegisterScript(params string[] scripts)
        {
            List<string> currentScripts = null;
            if (ViewData.ContainsKey("scripts")) currentScripts = ViewData["scripts"] as List<string>;
            else currentScripts = new List<string>();

            currentScripts.AddRange(scripts);
            ViewData["scripts"] = currentScripts;
        }

        public void RegisterStylesheet(params string[] styles)
        {
            List<string> currentStyles = null;
            if (ViewData.ContainsKey("styles")) currentStyles = ViewData["styles"] as List<string>;
            else currentStyles = new List<string>();

            currentStyles.AddRange(styles);
            ViewData["styles"] = currentStyles;
        }

        public void RegisterLocalizationScript()
        {
            RegisterScript(Name + "/" + Language + ".js");
        }
    }
}
